﻿/****************************************************************
  Author:  Ievgenii Nazaruk, ievgenii.nazaruk@gmail.com 
 License:  Microsoft Public License (Ms-PL)
          ( http://www.opensource.org/licenses/ms-pl.html or
            http://www.microsoft.com/opensource/licenses.mspx )
*****************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Frontend
{

    public enum SchoolName
    {
        KyivLivoberezhna = 4001,
        KyivUniversytet = 4002,
        KyivZhytomyrska = 4003,
        KyivPoshtova = 4004,
        KyivPecherska = 4005,
        KyivPoznyaky = 4006,
        KyivGolosiivska = 4007,
        OdesaRishelevskaya = 4101
    }

    public class LoginPanelRefreshEventArgs : EventArgs
    {
        public string User;
        public string Password;
        public SchoolName School;
        public LoginPanel Source;
    }
    
    public enum RefreshStatus
    {
        CanRefresh,
        Refreshing, 
        NoUser, 
        NoPassword, 
        CannotRefresh
    }

    /// <summary>
    /// Interaction logic for LoginPanel.xaml
    /// </summary>
    public partial class LoginPanel : UserControl, IStateSerializable
    {
        public static readonly DependencyProperty IsRefreshingProperty;
        public static readonly DependencyProperty RefreshStatusProperty;

        public static readonly DependencyProperty UserProperty;
        public static readonly DependencyProperty PasswordProperty;
        public static readonly DependencyProperty SchoolProperty;

        static LoginPanel()
        {
            FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = false;

            IsRefreshingProperty = DependencyProperty.Register("IsRefreshing", 
                                                                typeof(bool), 
                                                                typeof(LoginPanel),
                                                                metadata);

            metadata = new FrameworkPropertyMetadata();
            RefreshStatusProperty = DependencyProperty.Register("RefreshStatus",
                                                                typeof(RefreshStatus),
                                                                typeof(LoginPanel),
                                                                metadata);


            metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = "";
            metadata.DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            UserProperty = DependencyProperty.Register("User",
                                                            typeof(string),
                                                            typeof(LoginPanel),
                                                            metadata);

            metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = "";
            PasswordProperty = DependencyProperty.Register("Password",
                                                            typeof(string),
                                                            typeof(LoginPanel),
                                                            metadata);

            metadata = new FrameworkPropertyMetadata();
            metadata.DefaultValue = SchoolName.KyivLivoberezhna;
            SchoolProperty = DependencyProperty.Register("School",
                                                            typeof(SchoolName),
                                                            typeof(LoginPanel),
                                                            metadata);
        }

        public LoginPanel()
        {
            InitializeComponent();
            UpdateRefreshStatus();

            DependencyPropertyDescriptor passwordDescriptor = 
                DependencyPropertyDescriptor.FromProperty(PasswordProperty, typeof(LoginPanel));            
            passwordDescriptor.AddValueChanged(this, CredentialsChanged);

            DependencyPropertyDescriptor userDescriptor =
                DependencyPropertyDescriptor.FromProperty(UserProperty, typeof(LoginPanel));
            userDescriptor.AddValueChanged(this, CredentialsChanged);

            DependencyPropertyDescriptor schoolDescriptor =
                DependencyPropertyDescriptor.FromProperty(SchoolProperty, typeof(LoginPanel));
            schoolDescriptor.AddValueChanged(this, CredentialsChanged);
            
        }        

        void UpdateRefreshStatus()
        {
            RefreshStatus newStatus = RefreshStatus.CannotRefresh;

            if (IsRefreshing)
            {
                newStatus = RefreshStatus.Refreshing;
            }
            else
            {
                if (User.Length == 0)
                {
                    newStatus = RefreshStatus.NoUser;
                }
                else if (Password.Length == 0)
                {
                    newStatus = RefreshStatus.NoPassword;
                }
                else
                {
                    newStatus = RefreshStatus.CanRefresh;
                }
            }

            RefreshStatus = newStatus;
        }

        public RefreshStatus RefreshStatus
        {
            get
            {
                return (RefreshStatus)GetValue(RefreshStatusProperty);
            }
            private set
            {
                SetValue(RefreshStatusProperty, value);
            }
        }

        public bool IsRefreshing
        {
            set
            {
                SetValue(IsRefreshingProperty, value);
                UpdateRefreshStatus();
            }
            get
            {
                return (bool)GetValue(IsRefreshingProperty);
            }
        }

        public string User
        {
            get
            {
                return (string)GetValue(UserProperty);
            }
            set
            {
                SetValue(UserProperty, value);
            }
        }

        public string Password
        {
            get
            {
                return (String)GetValue(PasswordProperty);
            }
            set
            {
                SetValue(PasswordProperty, value);
            }
        }

        public SchoolName School
        {
            get
            {
                return (SchoolName)GetValue(SchoolProperty);
            }
            set
            {
                SetValue(SchoolProperty, value);
            }
        }
        
        
        public event EventHandler<LoginPanelRefreshEventArgs> Refresh;

        protected virtual void OnRefresh()
        {
            if (Refresh != null)
            {
                LoginPanelRefreshEventArgs args = new LoginPanelRefreshEventArgs();
                args.User = User;
                args.Password = Password;
                args.School = School;
                args.Source = this;

                Refresh(this, args);
            }
        }

        void CredentialsChanged(object sender, EventArgs e)
        {
            UpdateRefreshStatus();

            //Updating UI's password from our DP
            if (PasswordTextBox.Password != Password)
            {
                PasswordTextBox.Password = Password;
            }            

            //Updating School combo bolx UI from our DP
            bool found = true;
            foreach (ComboBoxItem item in SchoolComboBox.Items)
            {
                SchoolName curSchool = (SchoolName)item.Tag;
                if (curSchool == School)
                {
                    item.IsSelected = true;
                    break;
                }
            }

            if (!found)
            {
                throw new InvalidProgramException("Internal state is corrupt: school is not in the list.");
            }
        }

        void SchoolControlChanged(object sender, EventArgs e)
        {
            ComboBoxItem item = SchoolComboBox.SelectedItem as ComboBoxItem;

            if (item == null)
            {
                throw new InvalidProgramException("Internal state is corrupt: school is not selected or is of bad type.");
            }

            School = (SchoolName)item.Tag;
        }
        
        void PasswordControlChanged(object sender, EventArgs e)
        {
            SetValue(PasswordProperty, PasswordTextBox.Password);
        }

        private void RefreshClicked(object sender, RoutedEventArgs e)
        {
            OnRefresh();
        }

        private void NoUserClicked(object sender, RoutedEventArgs e)
        {
            Expander.IsExpanded = true;
            UserTextBox.Focus();
        }

        private void NoPasswordClicked(object sender, RoutedEventArgs e)
        {
            Expander.IsExpanded = true;
            PasswordTextBox.Focus();
        }

        public StateDictionary GetState()
        {
            StateDictionary state = new StateDictionary();
            state["IsExpanded"] = Expander.IsExpanded;
            state["Identity"] = User;
            state["IdentityV"] = Password;
            state["IdentityS"] = School;
            
            return state;
        }

        public void SetState(StateDictionary state)
        {
            Expander.IsExpanded = state.GetBoolean("IsExpanded");

            User = state.GetString("Identity");
            Password = state.GetString("IdentityV");
            School = (SchoolName)state["IdentityS"];
        }


    }
}
